<?php
/**
 * CGridPortlet class file.
 * Contém as classes CGridPortlet e CGridPortletEventHandler.
 *
 * @author Lucas Vasconcelos <contato@lucasvasconcelos.com>
 * @copyright Copyright(c) 2010 Lucas Vasconcelos
 * @license BSD License http://www.vasconcelossa.com.br/yap/license
 * @link http://www.vasconcelossa.com.br/yap/
 * @version $Id: CGridPortlet.php 21 2010-02-09 19:48:24Z contato@lucasvasconcelos.com $
 * @package yap.web.portlets
 */

Prado::using('yap.web.portlets.CPortlet');

/**
 * CGridPortlet class.
 *
 * @author Lucas Vasconcelos <contato@lucasvasconcelos.com>
 * @version 1.0 $Revision: 21 $
 * @package yap.web.portlets
 */
abstract class CGridPortlet extends CPortlet implements IPageGrid
{
	private $_gridManager=null;

	/**
	 * CGridPortlet requer um objeto CPageGrid como container.
	 */
	public function getRequiredParent()
	{
		return 'CPageGrid';
	}
	
	/**
	 * Este método é invocado durante o estágio OnInit.
	 * Este método dispara o evento 'OnSetupGrid' para acionar os manipuladores de evento.
	 * Se sobreescrever este método, certifique-se de chamar a implementação da classe pai para que
	 * os manipuladores de evento sejam acionados.
	 * @param TEventParameter parâmetro do evento que deve ser passado para os manipuladores de evento.
	 */
	public function onSetupGrid($param)
	{
		$this->raiseEvent('OnSetupGrid',$this,$param);
	}
	
	/**
	 * Este método é invocado durante o evento 'OnLoad' ou quando houver necessidade de modificar o objeto
	 * TActiveRecordCriteria.
	 * Este método dispara o evento 'OnSetupCriteria' para acionar os manipuladores de evento.
	 * Se sobreescrever este método, certifique-se de chamar a implementação da classe pai para que
	 * os manipuladores de evento sejam acionados.
	 * @param TEventParameter parâmetro do evento que deve ser passado para os manipuladores de evento.
	 */
	public function onSetupCriteria($param)
	{
		$this->raiseEvent('OnSetupCriteria',$this,$param);
	}
	
	/**
	 * Este método é invocado durante o evento 'OnLoad' ou quando houver necessidade de atualizar o
	 * conteúdo do objeto TDataGrid.
	 * Este método dispara o evento 'OnLoadGrid' para acionar os manipuladores de evento.
	 * Se sobreescrever este método, certifique-se de chamar a implementação da classe pai para que
	 * os manipuladores de evento sejam acionados.
	 * @param TEventParameter parâmetro do evento que deve ser passado para os manipuladores de evento.
	 */
	public function onLoadGrid($param)
	{
		$this->raiseEvent('OnLoadGrid',$this,$param);
	}
	
	/**
	 * Armazena valor do campo chave informado.
	 * @param string nome do campo chave.
	 * @param mixed valor do campo chave.
	 */
	public function setKey($key,$value)
	{
		$keys=$this->getKeys();
		$keys[$key]=$value;
		$this->setViewState('Keys',$keys,array());
	}
	
	/**
	 * Recupera o valor armazenado de um campo chave.
	 * @param string nome do campo chave.
	 * @return mixed
	 */
	public function getKey($value)
	{
		$keys=$this->getKeys();
		return (isset($keys[$value])) ? $keys[$value] : null;
	}
	
	/**
	 * Recupera vetor com todos os campos chave registrados.
	 * @return array
	 */
	public function getKeys()
	{
		return $this->getViewState('Keys',array());
	}
	
	/**
	 * @return CGridManager
	 */
	public function getGridManager()
	{
		if($this->_gridManager===null)
			$this->_gridManager=new CGridManager($this);
		return $this->_gridManager;
	}
	
	/**
	 * Registra event-handlers para os eventos disparados por {@link CGridPortlet}.
	 */
	public function onInit($param)
	{
		parent::onInit($param);
		$this->registerEventHandlers();
		
		Prado::trace('GridPortlet onSetupGrid()','yap.web.portlets');
		$this->onSetupGrid(null);
	}

	/**
	 * Executa método processRequest para tratar requisições do usuário.
	 */
	public function onLoad($param)
	{
		parent::onLoad($param);
		
		Prado::trace('GridPortlet processRequest()','yap.web.portlets');
		$this->processRequest();
	}
	
	protected function registerEventHandlers()
	{
		$this->attachEventHandler('OnSetupGrid',array('CGridEventHandler','setupGrid'));
		$this->attachEventHandler('OnSetupCriteria',array('CGridPortletEventHandler','setupCriteria'));
		$this->attachEventHandler('OnLoadGrid',array('CGridEventHandler','loadGrid'));
	}
	
	/**
	 * Processa requisição do usuário.
	 * Este método é invocado durante o estágio 'OnLoad'.
	 */
	protected function processRequest()
	{
		if(!$this->getPage()->getIsPostBack())
		{
			Prado::trace('GridPortlet clearCriteria()','yap.web.portlets');
			$this->getGridManager()->clearCriteria();
			
			Prado::trace('GridPortlet bindPortlet()','yap.web.portlets');
			$this->getPage()->bindPortlet($this);
			
			Prado::trace('GridPortlet onSetupCriteria()','yap.web.portlets');
			$this->onSetupCriteria(null);

			Prado::trace('GridPortlet onLoadGrid()','yap.web.portlets');
			$this->onLoadGrid(null);
		}
		else
			Prado::trace('GridPortlet postBack event.','yap.web.portlets');
	} 
}


/**
 * CGridPortletEventHandler class.
 *
 * @author Lucas Vasconcelos <contato@lucasvasconcelos.com>
 * @version 1.0 $Revision: 21 $
 * @package yap.web.portlets
 */
class CGridPortletEventHandler extends CGridEventHandler
{
	/**
	 * Responde ao evento OnSetupCriteria.
	 *
	 * Configura objeto TActiveRecordCriteria e o registra na sessão.
	 * Identifica parâmetros que coorespondem a chaves registradas na propriedade {@link getKeys Keys}.
	 */
	public static function setupCriteria(IPageGrid $sender,$param)
	{
		Prado::trace('GridPortletEventHandler setupCriteria()','yap.web.portlets');
		$criteria=$sender->getGridManager()->getCriteria();
		if($criteria->getCondition()=='')
			$criteria->setCondition($sender->getCriteriaCondition());

		foreach($sender->getKeys() as $key=>$value)
		{
			if(preg_match('/:\b'.$key.'\b/',$sender->getCriteriaCondition())>0)
				$criteria->Parameters[':'.$key]=$value;
		}
		$sender->getGridManager()->setCriteria($criteria);
	}
}